package com.wu.family.feed;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;



import android.R.integer;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;

public class InstaLoadImageMgr {
//	private Context 	mContext;
	public final static String 		PIC_CACHE_PATH = Environment.getExternalStorageDirectory() + "/family/.pic_cache/";
	private static InstaLoadImageMgr instance = null;
	private ExecutorService executorService = Executors.newFixedThreadPool(5);
	public Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
	
	private InstaLoadImageMgr()
	{
		File dir = new File(PIC_CACHE_PATH);
		if ( !dir.exists()) {
			dir.mkdirs();
		}
	}
	public static InstaLoadImageMgr getInstance()
	{
		if (instance == null) {
			instance = new InstaLoadImageMgr();
		}
		return instance;
	}
	public void removeImageCache(String urlString)
	{
		if (imageCache.containsKey(urlString)) {
			imageCache.remove(urlString);
		}
		File cacheFile = new File( PIC_CACHE_PATH + formatString( urlString ) );
		if ( cacheFile.exists() ) {
			cacheFile.delete();
		}
	}
	public Bitmap loadDrawble(final String picUrl, final ImageView view ,final ImageCallBack callBack)
	{
		final Handler  handler =  new Handler()
		 {
			public void handleMessage(Message msg) {
				if( msg.what == 0 )
				{
					imageCache.put(picUrl, new SoftReference<Bitmap>((Bitmap) msg.obj));
					if( callBack != null )
						callBack.setImage((Bitmap) msg.obj, picUrl, view);
				}else if( msg.what == 1 )
				{
					if ( msg.obj == null ) {
						System.out.println("**********【local null�?findlocalImage fail! *********");
						netLoadImage(picUrl, this);
					}else
					{
						if( callBack != null && view != null )
							callBack.setImage((Bitmap) msg.obj, picUrl, view);
					}
				}
				
			}; 
		 };
		if( callBack != null ) 
			view.setTag(picUrl);
		Bitmap bitmap = null;
		 if (imageCache.containsKey(picUrl) && false) {//由于�?��及时回收内存，所以不对内存进行软缓存
	            SoftReference<Bitmap> softReference = imageCache.get(picUrl);
	            bitmap = softReference != null ? softReference.get() : null;
	            if ( null == bitmap ) {
	            	imageCache.remove(picUrl);
	            	loadDrawble(picUrl,view,callBack);
	            	//return null;
				}else {
					if( callBack != null && !bitmap.isRecycled()) {
						callBack.setImage(bitmap, picUrl, view);
						System.out.println("******find img in cache!******");
						return bitmap;
					} else {
						imageCache.remove(picUrl);
		            	loadDrawble(picUrl,view,callBack);
		            	return null;
					}
				}
	            return bitmap;
		 }else
		 {
			 return findLocalImage(picUrl, handler); 
		 }
		//return null;
	}
	
	
	
	public Bitmap findLocalImage(final String imageUrl,final Handler handler)
	{
		Bitmap bitmap = null;
		FileInputStream inputStream = null;
		ObjectInputStream objectInputStream = null;
		try {
			File cacheFile = new File( PIC_CACHE_PATH + formatString( imageUrl ) );
			if ( cacheFile.exists() ) {
				System.out.println("cache exist!");
				inputStream = new FileInputStream(cacheFile);
				objectInputStream = new ObjectInputStream(inputStream);
				byte[] buffer = (byte[]) objectInputStream.readObject();
				//objectInputStream.read(buffer);
				bitmap = ByteArray2Drawable( buffer);
				//System.out.println("findlocalImage success!");
			}
			if(bitmap != null)
			{
				imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
			}
			if (handler != null) {
				handler.sendMessage(handler.obtainMessage(1, bitmap));
			}
			
		} catch (OutOfMemoryError e) {
			System.out.println("findlocalImage fail!---findLocalImage---");
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println("findlocalImage fail!---findLocalImage---");
			e.printStackTrace();
		} finally
		{
			try {
				if (inputStream != null ) {
					inputStream.close();
					inputStream = null;
				}
				if (objectInputStream != null ) {
					objectInputStream.close();
					objectInputStream = null;
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return bitmap;
	}
	
	public Bitmap findLocalImage(final String imageUrl, int size)
	{
		Bitmap bitmap = null;
		FileInputStream inputStream = null;
		ObjectInputStream objectInputStream = null;
		try {
			File cacheFile = new File( PIC_CACHE_PATH + formatString( imageUrl ) );
			if ( cacheFile.exists() ) {
				System.out.println("cache exist!");
				inputStream = new FileInputStream(cacheFile);
				objectInputStream = new ObjectInputStream(inputStream);
				byte[] buffer = (byte[]) objectInputStream.readObject();
				//objectInputStream.read(buffer);
				bitmap = ByteArray2Drawable( buffer, size);
				//System.out.println("findlocalImage success!");
			}
			if(bitmap != null)
			{
				imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
			}
			
		} catch (OutOfMemoryError e) {
			System.out.println("findlocalImage fail!---findLocalImage---");
			e.printStackTrace();
		} catch (Exception e) {
			System.out.println("findlocalImage fail!---findLocalImage---");
			e.printStackTrace();
		} finally
		{
			try {
				if (inputStream != null ) {
					inputStream.close();
					inputStream = null;
				}
				if (objectInputStream != null ) {
					objectInputStream.close();
					objectInputStream = null;
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return bitmap;
	}
	
	public Bitmap getLocalImage(final String imageUrl)
	{
		Bitmap bitmap = null;
		FileInputStream inputStream = null;
		ObjectInputStream objectInputStream = null;
		try {
			File cacheFile = new File( PIC_CACHE_PATH + formatString( imageUrl ) );
			if ( cacheFile.exists() ) {
				inputStream = new FileInputStream(cacheFile);
				objectInputStream = new ObjectInputStream(inputStream);
				byte[] buffer = (byte[]) objectInputStream.readObject();
				//objectInputStream.read(buffer);
				bitmap = ByteArray2Drawable( buffer);
			}
			if (objectInputStream!= null)
				objectInputStream.close();
//					drawable = Drawable.createFromStream(new URL(imageUrl).openStream(), "png");
			if(bitmap != null)
			{
				imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
				//System.out.println("loadDrawble---->" + imageUrl + "<load>");
				return bitmap;
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			Log.v("log img loading", "**********【Exception�?findlocalImage fail! *********");
			e.printStackTrace();
			return null;
		}
		
		return null;
				
	}
	
	public void loadImageFromUrl(String picUrl)
	{
		/*File file = new File(PIC_CACHE_PATH + formatString(picInfo.url));
		if (file.exists()) {
			return;
		}*/
		FileOutputStream outputStream = null;
		ObjectOutputStream	objectOutputStream = null ;
		Bitmap bitmap = null;
		//Bitmap saveBitmap = null;
		try {
			URL url = new URL(picUrl);
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5000);
			conn.setReadTimeout(25000);
			InputStream is = conn.getInputStream();
			BitmapFactory.Options opts = new Options();
			
			opts.inSampleSize = 1;
			//System.out.println("opts.inSampleSize:" + scale);
			opts.inJustDecodeBounds = false;
			opts.inPreferredConfig = Config.RGB_565;
			opts.inInputShareable = true;
			opts.inPurgeable = true;
			bitmap = BitmapFactory.decodeStream(is, null, opts);
			/*int width = bitmap.getWidth();
			int height = bitmap.getHeight();
			if (isLan && (double)width / (double)height < 4f/3f) {
				height = (width * 3) / 4;
			}else if ((double)width / (double)height < 2f/3f) {
				height = (width * 3) / 2;
			}
			if (height < bitmap.getHeight()) {
				saveBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
			}else {
				saveBitmap = bitmap;
			}*/
			if (bitmap != null) {
				checkCacheCount();
				File bmFile = new File(PIC_CACHE_PATH + formatString(picUrl));
				if (bmFile.exists()) {
					bmFile.delete();
				}
				bmFile.createNewFile();
				outputStream = new FileOutputStream(bmFile);
				objectOutputStream = new ObjectOutputStream(outputStream);
				objectOutputStream.writeObject( drawable2ByteArray(bitmap) );
				objectOutputStream.flush();
				outputStream.flush();
			}
		}catch (OutOfMemoryError err){
			System.out.println("OutOfMemoryError---loadImageFromUrl");
			err.printStackTrace();
		}catch (SocketTimeoutException e) {
			System.out.println("SocketTimeoutException---loadImageFromUrl");
			e.printStackTrace();
		}catch (MalformedURLException e) {
			System.out.println("MalformedURLException---loadImageFromUrl");
			e.printStackTrace();
		}catch (IOException e) {
			System.out.println("IOException---loadImageFromUrl");
			e.printStackTrace();
		}catch (Exception e) {
			System.out.println("Exception---loadImageFromUrl");
			e.printStackTrace();
		}finally {
			try {
				//StringTools.rececleBm(bitmap);
				if (objectOutputStream != null ) {
					objectOutputStream.close();
					objectOutputStream = null;
				}
				if (outputStream != null ) {
					outputStream.close();
					outputStream = null;
				}
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	
	}
	
	public void netLoadImage(final String picUrl,final Handler handler)
	{
		executorService.submit(new Runnable() {
			@Override
			public void run() {
				FileOutputStream outputStream = null;
				ObjectOutputStream	objectOutputStream = null ;
				Bitmap bitmap = null;
				//Bitmap saveBitmap = null;
				try {
					URL url = new URL(picUrl);
					HttpURLConnection conn = (HttpURLConnection)url.openConnection();
					conn.setReadTimeout(5000);
					conn.setReadTimeout(25000);
					InputStream is = conn.getInputStream();
					BitmapFactory.Options opts = new Options();
					
					opts.inSampleSize = 1;
					opts.inJustDecodeBounds = false;
					opts.inPreferredConfig = Config.RGB_565;
					opts.inInputShareable = true;
					opts.inPurgeable = true;
					bitmap = BitmapFactory.decodeStream(is, null, opts);
					/*int width = bitmap.getWidth();
					int height = bitmap.getHeight();
					if (isLan && (double)width / (double)height < 4f/3f) {
						height = (width * 3) / 4;
					}else if ((double)width / (double)height < 2f/3f) {
						height = (width * 3) / 2;
					}
					if (height < bitmap.getHeight()) {
						saveBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
					}else {
						saveBitmap = bitmap;
					}*/
					
					if (bitmap != null) {
						handler.sendMessage(handler.obtainMessage(0, bitmap));
						checkCacheCount();
						File bmFile = new File(PIC_CACHE_PATH + formatString(picUrl));
						if (bmFile.exists()) {
							bmFile.delete();
						}
						bmFile.createNewFile();
						outputStream = new FileOutputStream(bmFile);
						objectOutputStream = new ObjectOutputStream(outputStream);
						objectOutputStream.writeObject( drawable2ByteArray(bitmap) );
						objectOutputStream.flush();
						outputStream.flush();
					}
					System.out.println("net load success!---netLoadImage");
				}catch (OutOfMemoryError err){
					System.out.println("OutOfMemoryError---netLoadImage");
					err.printStackTrace();
				}catch (SocketTimeoutException e) {
					System.out.println("SocketTimeoutException---netLoadImage");
					e.printStackTrace();
				}catch (MalformedURLException e) {
					System.out.println("MalformedURLException---netLoadImage");
					e.printStackTrace();
				}catch (IOException e) {
					System.out.println("IOException---netLoadImage");
					e.printStackTrace();
				}finally {
					try {
						/*if (!saveBitmap.equals(bitmap)) {
							StringTools.rececleBm(bitmap);
						}*/
						if (objectOutputStream != null ) {
							objectOutputStream.close();
							objectOutputStream = null;
						}
						if (outputStream != null ) {
							outputStream.close();
							outputStream = null;
						}
						
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		});
	}
	public byte[] drawable2ByteArray(final Bitmap bitmap)
	{
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.JPEG, 100, baos);
		byte[] drawableArray = baos.toByteArray();
		try {
			baos.flush();
			baos.close();
			baos = null;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if ( baos != null ) {
					baos.close();
					baos = null;
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
		}
		
		return drawableArray;
	}
	public Bitmap ByteArray2Drawable(byte[] drawableArray)
	{
		Bitmap bitmap = null;
		try {
			bitmap = BitmapFactory.decodeByteArray(drawableArray, 0, drawableArray.length);
		} catch (OutOfMemoryError e) {
			System.out.println("OutOfMemoryError!---ByteArray2Drawable()---");
			e.printStackTrace();
			BitmapFactory.Options options = new Options();
			options.inJustDecodeBounds = false;
			options.inSampleSize = 2;
			try {
				bitmap = BitmapFactory.decodeByteArray(drawableArray, 0, drawableArray.length, options);
			} catch (OutOfMemoryError e2) {
				e2.printStackTrace();
			}
			
		}
		return bitmap;
	}
	public Bitmap ByteArray2Drawable(byte[] drawableArray, int inSampleSize)
	{
		Bitmap bitmap = null;
		try {
			BitmapFactory.Options options = new Options();
			options.inJustDecodeBounds = false;
			options.inPreferredConfig = Config.RGB_565;
			options.inSampleSize = inSampleSize;
			options.inInputShareable = true;
			options.inPurgeable = true;
			bitmap = BitmapFactory.decodeByteArray(drawableArray, 0, drawableArray.length, options);
		} catch (OutOfMemoryError e) {
			return ByteArray2Drawable(drawableArray, inSampleSize + 1);
			
		}
		return bitmap;
	}
	public ImageCallBack imageCallBack = new ImageCallBack() {
		
		@Override
		public void setImage(Bitmap bitmap, String url, ImageView view) {
			if(url.equals((String)view.getTag()))
			{
				view.setImageBitmap(bitmap);
			}
		}
	};
	public String clearTail(final String from )
	{
		String s_notTail = null;
		int find = from.indexOf("!");
		if( find != -1 )
		{
			s_notTail = from.substring(0, find+1);
		}
		return s_notTail;
	}
	public static String formatString( final String from )
	{
		String formatString = new String(from);
		String[] strs = formatString.split("/");
		formatString = "";
		for( int i=0; i<strs.length; i++ )
		{
			formatString = formatString + strs[i];
		}
		formatString = formatString.substring(formatString.lastIndexOf("com"));
		return formatString;
	}
	public interface ImageCallBack
	{
		public void setImage(Bitmap bitmap,String url, ImageView view);
	}
	public interface TemplateImageCallBack
	{
		public void setImage(Bitmap bitmap,String url, View view);
	}
	public String getMiddleHead( String avatar )
	{
		return avatar.replace("small", "middle");
	}
	
	public String getBigHead( String avatar )
	{
		return avatar.replace("small", "big");
	}
	
	
	public void checkCacheCount()
	{
		File cacheDirFile = new File(Environment.getExternalStorageDirectory() + "/family/.pic_cache");
		if (!cacheDirFile.exists()) {
			cacheDirFile.mkdirs();
		}
		if( cacheDirFile.list().length > 500)
		{
			delAllFile(Environment.getExternalStorageDirectory() + "/family/.pic_cache");
		}
	}
	/**
     * 删除文件�?
     * @param filePathAndName String 文件夹路径及名称 如c:/fqf
     * @param fileContent String
     * @return boolean
     */
    public void delFolder(String folderPath) {
            try {
                    delAllFile(folderPath); //删除完里面所有内�?
                    String filePath = folderPath;
                    filePath = filePath.toString();
                    java.io.File myFilePath = new java.io.File(filePath);
                    myFilePath.delete(); //删除空文件夹
            }
            catch (Exception e) {
                    e.printStackTrace();

            }
    }
	 /**
     * 删除文件夹里面的�?��文件
     * @param path String 文件夹路�?�?c:/fqf
     */
    public void delAllFile(String path) {
            File file = new File(path);
            if (!file.exists()) {
                    return;
            }
            if (!file.isDirectory()) {
            	return;
            }
            String[] tempList = file.list();
            File temp = null;
            for (int i = 0; i < tempList.length; i++) {
                    if (path.endsWith(File.separator)) {
                            temp = new File(path + tempList[i]);
                    }
                    else {
                            temp = new File(path + File.separator + tempList[i]);
                    }
                    if (temp.isFile()) {
                            temp.delete();
                    }
                    if (temp.isDirectory()) {
                            delAllFile(path+"/"+ tempList[i]);//先删除文件夹里面的文�?
                            delFolder(path+"/"+ tempList[i]);//再删除空文件�?
                    }
            }
    }
}
